package com.cskaoyan.service.wx.cart;

import com.cskaoyan.dao.wx.WxOrderDao;
import com.cskaoyan.dao.wx.adress.WXAddressDao;
import com.cskaoyan.dao.wx.cart.WXCartMapper;
import com.cskaoyan.exception.wx.cart.WxCartException;
import com.cskaoyan.model.admin.goodsbean.OrderGoods;
import com.cskaoyan.model.admin.marketbeans.pojo.MarketOrder;
import com.cskaoyan.model.realm.WxLoginUserData;
import com.cskaoyan.model.wx.cart.*;
import com.cskaoyan.model.wx.wxadressbean.vo.WXAddressDetailVo;
import com.cskaoyan.utils.BeanCreateUtils;
import com.cskaoyan.utils.DateUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Author:
 * @description:
 * @keypoint:
 * @tags:
 * @related:
 */
@Service
public class WxCartServiceImpl implements WxCartService {
    @Autowired
    WXCartMapper wxCartMapper;

    @Autowired
    WxOrderDao wxOrderMapper;

    @Autowired
    WXAddressDao wxAddressMapper;


    @Override
    public Integer selectGoodsCountInCart() throws WxCartException {
        Subject subject = SecurityUtils.getSubject();
        WxLoginUserData principal = (WxLoginUserData) subject.getPrincipal();
        Integer id = principal.getId();
        Integer num = null;
        try {
            num = wxCartMapper.selectCountGoodsNumByUserID(id);
        } catch (Exception e) {
            e.printStackTrace();
            throw new WxCartException("购物车查询异常");
        }
        //如果没有要返回0
        if(num == null){
            num = 0;
        }
        return num;
    }

    /**
     * 返回的是插入数据库的自增id
     *
     * @param goodsAndProductAndNumber
     * @return
     */
    @Override
    public Integer insertItemToCart(GoodsAndProductAndNumber goodsAndProductAndNumber,Boolean fastMode) throws WxCartException {

        Subject subject = SecurityUtils.getSubject();
        WxLoginUserData principal = (WxLoginUserData) subject.getPrincipal();
        //get userid from subject
        Integer id = principal.getId();

        //如果是fastadd，就不用去try
        Integer tryUpdate = 0;

        if(!fastMode) {
            // 增加一样的话，直接加number就好了，
            tryUpdate = wxCartMapper.tryUpdateProductNumber(goodsAndProductAndNumber.getProductId(), goodsAndProductAndNumber.getNumber(), id);
        }

        if(tryUpdate != 1) {
            Cart goodsProductInfo = null;

            //get goods and product information from market_goods by goods id;
            try {
                goodsProductInfo = wxCartMapper.selectGoodsProductInfoByGoodsIdAndProductId(goodsAndProductAndNumber);

                //用户选择的数量
                goodsProductInfo.setNumber(goodsAndProductAndNumber.getNumber());
                goodsProductInfo.setGoodsId(goodsAndProductAndNumber.getGoodsId());
                goodsProductInfo.setProductId(goodsAndProductAndNumber.getProductId());
                goodsProductInfo.setUserId(id);
                Date time = DateUtils.getNowDate();
                goodsProductInfo.setAddTime(time);
                goodsProductInfo.setUpdateTime(time);
                goodsProductInfo.setDeleted(false);
                Integer result = wxCartMapper.insertCart(goodsProductInfo);
            } catch (Exception e) {
                e.printStackTrace();
                throw new WxCartException("add cart error");
            }
            return goodsProductInfo.getId();
        }

        //这个返回随便
        return 1;


    }

    @Override
    public CartIndexVO selectCartInfo() throws InstantiationException, IllegalAccessException, WxCartException {
        CartIndexVO cartIndexVO = null;
        Subject subject = SecurityUtils.getSubject();
        WxLoginUserData principal = (WxLoginUserData) subject.getPrincipal();
        Integer id = principal.getId();
        try {
            List<Cart> cartListDTO = wxCartMapper.selectAllCartInfo(id, null);


            Integer goodsCount = 0;
            Integer checkedGoodsCount = 0;
            BigDecimal goodsAmount = new BigDecimal("0");
            BigDecimal checkGoodsAmount = new BigDecimal("0");

//            MathContext mathContext = new MathContext(2);
            for (Cart listDTO : cartListDTO) {
                Integer count = Integer.valueOf(listDTO.getNumber());
                goodsCount += count;
                BigDecimal price = listDTO.getPrice();
                BigDecimal multiplyResult = price.multiply(new BigDecimal(count));
                goodsAmount = goodsAmount.add(multiplyResult);

                if (listDTO.getChecked()) {
                    checkedGoodsCount += count;
                    checkGoodsAmount = checkGoodsAmount.add(multiplyResult);
                }
            }

            CartIndexVO.CartTotalDTO bean = BeanCreateUtils.createBean(CartIndexVO.CartTotalDTO.class, goodsCount, checkedGoodsCount, goodsAmount, checkGoodsAmount);

            cartIndexVO = BeanCreateUtils.createBean(CartIndexVO.class, bean, cartListDTO);
        } catch (Exception e) {
            throw new WxCartException("add cart wrong");
        }
        return cartIndexVO;
    }

    @Override
    public Integer updateCartInfo(CartUpdateBO cartUpdateBO) throws WxCartException {
        Integer result = null;
        try {
            result = wxCartMapper.updateCartInfoById(cartUpdateBO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new WxCartException("update cart error");
        }

        return result;

    }

    @Override
    public Integer updateCartChecked(ProductIdsAndChecked productIdsAndChecked) throws WxCartException {
        Integer result = null;
        try {
            result = wxCartMapper.updateCartCheckedByProductIds(productIdsAndChecked);
        } catch (Exception e) {
            e.printStackTrace();
            throw new WxCartException("update checked error");
        }

        return result;
    }

    @Override
    public Integer deleteCart(List<Integer> productIds1) throws WxCartException {
        Integer result = null;
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();
        try {
            result = wxCartMapper.deleteCartByProductIds(productIds1,userId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new WxCartException("delete cart error");
        }
        return result;
    }

    @Override
    public CheckOutVO getCheckOutInfo(CheckOut checkOut) throws InstantiationException, IllegalAccessException, WxCartException {
        //获取userId
        Subject subject = SecurityUtils.getSubject();
        WxLoginUserData principal = (WxLoginUserData) subject.getPrincipal();
        Integer userId = principal.getId();

        Integer cartId = checkOut.getCartId();
        Integer addressId = checkOut.getAddressId();

        //这个是要返回的
        CheckOutVO bean = null;
        try {
            //当cartId为0的时候，取出该用户下的所有checked的购物车的信息
            if(userId == null || cartId == null){
                throw new WxCartException("checkOut: userId or cartId is null");
            }
            List<Cart> checkedGoodsListDTO = wxCartMapper.selectAllCartInfo(userId, cartId);

            Integer cartGoodsSize = checkedGoodsListDTO.size();
            //根据addressid取出地址详情
            WXAddressDetailVo wxAddressDetailVo = wxAddressMapper.selectAddressDetail(addressId);



            //优惠券的处理
            Integer couponId = checkOut.getCouponId();
            Integer userCouponId = checkOut.getUserCouponId();
            Integer grouponRulesId = checkOut.getGrouponRulesId();
            Integer availableCouponLength = 0;

            //从market_system里面取出freightPrice；
            String systemFreightPrice = wxCartMapper.selectFreightPrice();
            Integer systemFreightPriceInt = Integer.valueOf(systemFreightPrice);
            String minNeedPrice = wxCartMapper.selectMinNeedFreightPrice();
            Integer minNeedPriceInt = Integer.valueOf(minNeedPrice);
            BigDecimal couponPrice = new BigDecimal(0);
            BigDecimal grouponPrice = new BigDecimal(0);

            if (couponId > 0 && userCouponId > 0) {
                //通过couponId 选出 couponPrice
                couponPrice = wxCartMapper.selectDiscountFromMarketCouponByCouponId(couponId);
                //通过userCouponId设置coupon为已使用
                wxCartMapper.updateCouponStatusByUserCouponId(userCouponId);
                //通过userId选出还有几张coupon可以用 -- availableCouponLength
                availableCouponLength = wxCartMapper.selectCountCouponByUserId(userId);

            }

            if (grouponRulesId > 0) {
                //通过groupRulesId 选出groupPrice
                grouponPrice = wxCartMapper.selectDiscountFromMarketGrouponRulesByGroupRulesId(grouponRulesId);
                //todo: 要不要插入market_groupon表？？？如果要的话，那就要创建订单之后？
                //todo: 那groupon_id 从哪来？团购活动id，开团用户就是0
            }

            BigDecimal goodsTotalPrice = new BigDecimal(0);
            MathContext mathContext = new MathContext(2);
            for (Cart cart : checkedGoodsListDTO) {
                BigDecimal multiply = cart.getPrice().multiply(new BigDecimal(cart.getNumber()), mathContext);
                goodsTotalPrice = goodsTotalPrice.add(multiply);
            }
            BigDecimal orderTotalPrice = goodsTotalPrice;



            BigDecimal freightPrice = new BigDecimal(0);//todo: 怎么处理
            if(orderTotalPrice.compareTo(new BigDecimal(minNeedPriceInt))  == -1){
                freightPrice = new BigDecimal(systemFreightPriceInt);
            }
            BigDecimal actualPrice = orderTotalPrice.add(freightPrice).subtract(couponPrice).subtract(grouponPrice);

            if(actualPrice.compareTo(BigDecimal.ZERO) == -1){
                actualPrice = new BigDecimal(0);
            }

            bean = BeanCreateUtils.createBean(CheckOutVO.class,
                    grouponRulesId,
                    actualPrice,
                    orderTotalPrice,
                    cartId,
                    userCouponId,
                    couponId,
                    goodsTotalPrice,
                    addressId,
                    grouponPrice,
                    wxAddressDetailVo,
                    couponPrice,
                    availableCouponLength,
                    freightPrice,
                    checkedGoodsListDTO);

        } catch (Exception e) {
            e.printStackTrace();
            throw new WxCartException("checkout error");
        }
        return bean;
    }
}
